package com.neuronbit.businessflow.intellij.psi;

import com.intellij.openapi.util.TextRange;
import com.intellij.psi.ElementManipulator;
import com.intellij.util.IncorrectOperationException;
import com.neuronbit.businessflow.intellij.antlr.BpmParser;
import org.antlr.intellij.adaptor.lexer.RuleIElementType;
import org.antlr.intellij.adaptor.psi.ANTLRPsiNode;
import org.apache.commons.lang3.NotImplementedException;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import static org.apache.commons.lang3.StringUtils.substring;

/**
 * The type Antlr psi node manipulator.
 */
public class ANTLRPsiNodeManipulator implements ElementManipulator<ANTLRPsiNode> {
    @Nullable
    @Override
    public ANTLRPsiNode handleContentChange(@NotNull ANTLRPsiNode element, @NotNull TextRange range, String newContent) throws IncorrectOperationException {
        if (element.getNode().getElementType() instanceof RuleIElementType && ((RuleIElementType) element.getNode().getElementType()).getRuleIndex() == BpmParser.RULE_callDef) {
            String originText = element.getText();
            String newText = substring(originText, 0, range.getStartOffset())
                    + newContent
                    + substring(originText, range.getEndOffset());
            return (ANTLRPsiNode) element.replace(SimpleElementFactory.createCall(element.getProject(), newText));
        } else {
            throw new NotImplementedException("handleContentChange got unexpected element");
        }
    }

    @Nullable
    @Override
    public ANTLRPsiNode handleContentChange(@NotNull ANTLRPsiNode element, String newContent) throws IncorrectOperationException {
        return SimpleElementFactory.createString(element.getProject(), newContent);
    }

    @Override
    public @NotNull TextRange getRangeInElement(@NotNull ANTLRPsiNode element) {
        return new TextRange(element.getTextOffset(), element.getTextOffset() + element.getTextLength());
    }
}
